package com.sztx.pay.center.common.util;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.sztx.se.common.util.date.DateUtil;

/**
 * MsgSrv请求(应答)
 * @author YangChao
 * @since 20140218
 * @version 1.2
 * <p>修改记录:
 * <br>20140220: 将三种发送方式抽象成接口  @by yangchao
 * <br>20140327: 添加API，可直接将消息转换成对应的类型，将<b>getValue(..)</b>更改为<b>getString(..)</b>
 * </p>
 */
public class MsgSrvRsp {
	private InMessage inMessage;
	private String message;
	private String[] datas;
	
	/**
	 * MsgSrv请求(应答)
	 * @param connector 连接
	 * @param message 源报文
	 */
	public MsgSrvRsp(String message) {
		if (message == null || message.isEmpty()) {
			throw new IllegalArgumentException("null or empty message");
		}
		this.message = message;
		initialize(); // 解析基础数据
	}
	
	/**
	 * 初始化数据
	 */
	private void initialize() {
		this.inMessage = new InMessage(message);
		this.datas = getMessage().split(" ");
	}

	/**
	 * 获取AppName
	 * @return 完整PppName
	 */
	public String getAppName() {
		return inMessage.getAppName();
	}
	
	/**
	 * 获取短AppName
	 * @return 短AppName
	 */
	public String getShortAppName() {
		String fullName = inMessage.getAppName();
		return fullName.substring(0, fullName.indexOf("."));
	}

	/**
	 * 获取Cmd
	 * @return CMD
	 */
	public String getCmd() {
		return inMessage.getCmd();
	}

	/**
	 * 获取消息报文
	 * @return
	 */
	public String getMessage() {
		return inMessage.getMessage();
	}
	
	/**
	 * 根据Key来获取参数值
	 * @param key 键值对中的键(key),即：<b>key</b>-value
	 * @return 如果值是<b>NA</b>，则返回空<b>""</b>, 否则返回源数据
	 */
	public String getString(String key) {
		if (key == null || key.isEmpty()) {
			throw new IllegalArgumentException("key should not be null or empty");
		}
		if (datas != null && datas.length > 0) {
			String prefix = key + "=";
			for (String param : datas) {
				if (param.trim().startsWith(prefix)) {
					String value = param.replace(prefix, "");
					return "NA".equals(value) ? "" : value; // 当参数值是NA的时候，返回""
				}
			}
		}
		return "";
	}
	
	/**
	 * 根据参数下标(顺序)来获取参数值，下标从<b> 0 </b>开始
	 * @param index 下标(>=0)
	 * @return 如果值是<b>NA</b>，则返回空<b>""</b>, 否则返回源数据
	 */
	public String getString(int index) {
		if (index < 0) {
			throw new IllegalArgumentException("index of pairs should not be >=0");
		}
		if (index >= datas.length) {
			throw new IndexOutOfBoundsException("max index of request parameters is(-1 means no param): " + (datas.length - 1));
		}
		String pairs = datas[index];
		if (pairs.contains("=")) {
			String value = pairs.trim().replaceAll("( \\w+)=", "").trim();// 正则表达式 去掉" key="
			return "NA".equals(value) ? "" : value; // 当参数值是NA的时候，返回""
		} else {
			return pairs;
		}
	}
	
	/**
	 * 根据Key来获取参数值
	 * @param key 键值对中的键(key),即：<b>key</b>-value
	 * @return 返回转换后的数字，如果不是<b>Integer</b>，会抛出NumberFormatException
	 */
	public Integer getInteger(String key) {
		return Integer.parseInt(getString(key));
	}
	
	/**
	 * 根据参数下标(顺序)来获取参数值，下标从<b> 0 </b>开始
	 * @param index 下标(>=0)
	 * @return 返回转换后的数字，如果不是<b>Integer</b>，会抛出NumberFormatException
	 */
	public Integer getInteger(int index) {
		return Integer.parseInt(getString(index));
	}
	
	/**
	 * 根据Key来获取参数值
	 * @param key 键值对中的键(key),即：<b>key</b>-value
	 * @return 返回转换后的数字，如果不是<b>Long</b>，会抛出NumberFormatException
	 */
	public Long getLong(String key) {
		return Long.parseLong(getString(key));
	}
	
	/**
	 * 根据参数下标(顺序)来获取参数值，下标从<b> 0 </b>开始
	 * @param index 下标(>=0)
	 * @return 返回转换后的数字，如果不是<b>Long</b>，会抛出NumberFormatException
	 */
	public Long getLong(int index) {
		return Long.parseLong(getString(index));
	}
	
	/**
	 * 根据Key来获取参数值
	 * @param key 键值对中的键(key),即：<b>key</b>-value
	 * @return 返回转换后的数字，如果不是<b>Short</b>，会抛出NumberFormatException
	 */
	public Short getShort(String key) {
		return Short.parseShort(getString(key));
	}
	
	/**
	 * 根据参数下标(顺序)来获取参数值，下标从<b> 0 </b>开始
	 * @param index 下标(>=0)
	 * @return 返回转换后的数字，如果不是<b>Short</b>，会抛出NumberFormatException
	 */
	public Short getShort(int index) {
		return Short.parseShort(getString(index));
	}
	
	/**
	 * 根据Key来获取参数值
	 * @param key 键值对中的键(key),即：<b>key</b>-value
	 * @return 返回转换后的数字，如果不是<b>Double</b>，会抛出NumberFormatException
	 */
	public Double getDouble(String key) {
		return Double.parseDouble(getString(key));
	}
	
	/**
	 * 根据参数下标(顺序)来获取参数值，下标从<b> 0 </b>开始
	 * @param index 下标(>=0)
	 * @return 返回转换后的数字，如果不是<b>Double</b>，会抛出NumberFormatException
	 */
	public Double getDouble(int index) {
		return Double.parseDouble(getString(index));
	}
	
	/**
	 * 根据Key来获取参数值
	 * @param key 键值对中的键(key),即：<b>key</b>-value
	 * @return 返回转换后的数字，如果不是<b>Float</b>，会抛出NumberFormatException
	 */
	public Float getFloat(String key) {
		return Float.parseFloat(getString(key));
	}
	
	/**
	 * 根据参数下标(顺序)来获取参数值，下标从<b> 0 </b>开始
	 * @param index 下标(>=0)
	 * @return 返回转换后的数字，如果不是<b>Float</b>，会抛出NumberFormatException
	 */
	public Float getFloat(int index) {
		return Float.parseFloat(getString(index));
	}
	
	/**
	 * 根据Key来获取参数值
	 * @param key 键值对中的键(key),即：<b>key</b>-value
	 * @return 返回转换后的日期，默认时间格式 <b>yyyyMMddHHmmss</b>
	 */
	public Date getDate(String key) {
		return getDate(key, "yyyyMMddHHmmss");
	}
	
	/**
	 * 根据Key来获取参数值
	 * @param key 键值对中的键(key),即：<b>key</b>-value
	 * @param pattern 时间转换模式
	 * @return 返回转换后的日期
	 */
	public Date getDate(String key, String pattern) {
		return DateUtil.parse(getString(key), pattern);
	}
	
	/**
	 * 根据参数下标(顺序)来获取参数值，下标从<b> 0 </b>开始
	 * @param index 下标(>=0)
	 * @return 返回转换后的日期，默认时间格式 <b>yyyyMMddHHmmss</b>
	 */
	public Date getDate(int index) {
		return getDate(index, "yyyyMMddHHmmss");
	}
	
	/**
	 * 根据参数下标(顺序)来获取参数值，下标从<b> 0 </b>开始
	 * @param index 下标(>=0)
	 * @param pattern 时间转换模式
	 * @return 返回转换后的日期
	 */
	public Date getDate(int index, String pattern) {
		return DateUtil.parse(getString(index), pattern);
	}
	
	/**
	 * 将消息转换成Key-Value形式
	 * @return 消息MAP
	 */
	public Map<String, String> toMap() {
		String[] data = inMessage.getMessage().split(" ");
		Map<String, String> map = new HashMap<String, String>();
		if (data != null && data.length > 2) { // APPNAME CMD MESSAGE
			for (int i = 2; i < data.length; i++) {
				String[] elements = data[i].split("=", 2);
				String key   = elements[0];
				String value = elements[1];
				map.put(key, value);
			}
		}
		return map;
	}
	
	public String toString() {
		return inMessage.toString();
	}

	/**
	 * MsgSrv消息报文实体
	 * @author YangChao
	 * @since 20140218
	 * @version 1.0
	 */
	class InMessage {
		private String appName;
		private String cmd;
		private String connId;
		private String message;
		
		/**
		 * 创建一个MsgSrv消息实体，源数据格式(APPNAME CMD MESSAGE)
		 * @param message 报文
		 */
		public InMessage(Object message) {
			this((String) message);
		}
		
		/**
		 * 创建一个MsgSrv消息实体，源数据格式(APPNAME CMD MESSAGE)
		 * @param message 报文
		 */
		public InMessage(String message) {
			String[] data = message.split(" ", 4);
			this.appName = data[0];
			this.cmd = data[1];
			this.connId = data[2];
			if (data.length > 3) { // MESSAGE可能为空
				this.message = data[3];
			} else {
				this.message = "";
			}
		}
	
		public String getAppName() {
			return appName;
		}
	
		public void setAppName(String appName) {
			this.appName = appName;
		}
	
		public String getCmd() {
			return cmd;
		}
	
		public void setCmd(String cmd) {
			this.cmd = cmd;
		}
	
		public String getConnId() {
			return connId;
		}
	
		public void setConnId(String connId) {
			this.connId = connId;
		}
	
		public String getMessage() {
			return message;
		}
	
		public void setMessage(String message) {
			this.message = message;
		}
		
		public String toString() {
			return appName + " " + cmd + " " + message;
		}
	}
}
